Passed
Push — next ( 9aca7d...a2fe89 )
by Roy
01:49
created

OSPaths.ts ➔ joinPathToBase   B

Complexity

Conditions 7

Size

Total Lines 3
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 3
rs 8
c 0
b 0
f 0
cc 7
1
// # spell-checker:ignore AllUsersProfile HomeDrive HomePath LocalAppData UserProfile WinDir falsey
2
3
import { Platform } from '../platform-adapters/_base';
4
5
/** Determine common OS/platform paths (home, temp, ...) */
6
export type OSPaths = {
7
	/** @constructor Create an `OSPaths` object. */
8
	(): OSPaths;
9
	/** @constructor Create an `OSPaths` object. */
10
	new (): OSPaths;
11
	/* eslint-disable functional/no-method-signature */
12
	/** Returns the path string of the user's home directory (or `undefined`if the user's home directory is not resolvable). */
13
	home(): string | undefined;
14
	/** Returns the path string of the system's default directory for temporary files. */
15
	temp(): string;
16
	/* eslint-enable functional/no-method-signature */
17
};
18
19
function isEmpty(s: string | null | undefined): boolean {
20
	return !s; // reminder: JS "falsey" == [undefined, null, NaN, 0, '', false]
21
}
22
23
// eslint-disable-next-line @typescript-eslint/no-namespace
24
namespace Adapt {
25
	export const isWinOS = (adapter_: Platform.Adapter) => /^win/i.test(adapter_.process.platform);
26
27
	export const normalizePath = (adapter_: Platform.Adapter) => {
28
		return (path_: string | undefined): string | undefined => {
29
			return path_ ? adapter_.path.normalize(adapter_.path.join(path_, '.')) : void 0;
30
		};
31
	};
32
33
	export const home = (adapter_: Platform.Adapter) => {
34
		const { env, os, path } = adapter_;
35
36
		const isWinOS = Adapt.isWinOS(adapter_);
37
		const normalizePath = Adapt.normalizePath(adapter_);
38
39
		const posix = () =>
40
			normalizePath((typeof os.homedir === 'function' ? os.homedir() : void 0) || env.get('HOME'));
41
42
		const windows = () => {
43
			const priorityList = [
44
				typeof os.homedir === 'function' ? os.homedir() : void 0,
45
				env.get('USERPROFILE'),
46
				env.get('HOME'),
47
				env.get('HOMEDRIVE') || env.get('HOMEPATH')
48
					? path.join(env.get('HOMEDRIVE') || '', env.get('HOMEPATH') || '')
49
					: void 0,
50
			];
51
			return normalizePath(priorityList.find((v) => !isEmpty(v)));
52
		};
53
54
		return isWinOS ? windows : posix;
55
	};
56
57
	export const temp = (adapter_: Platform.Adapter) => {
58
		const { env, os, path } = adapter_;
59
60
		const isWinOS = Adapt.isWinOS(adapter_);
61
		const normalizePath = Adapt.normalizePath(adapter_);
62
63
		function joinPathToBase(base: string | undefined, segments: readonly string[]) {
64
			return base ? path.join(base, ...segments) : void 0;
65
		}
66
67
		const posix = () => {
68
			const fallback = '/tmp';
69
			const priorityList = [
70
				typeof os.tmpdir === 'function' ? os.tmpdir() : void 0,
71
				env.get('TMPDIR'),
72
				env.get('TEMP'),
73
				env.get('TMP'),
74
			];
75
			return normalizePath(priorityList.find((v) => !isEmpty(v))) || fallback;
76
		};
77
78
		const windows = () => {
79
			const fallback = 'C:\\Temp';
80
			const priorityListLazy = [
81
				os.tmpdir,
82
				() => env.get('TEMP'),
83
				() => env.get('TMP'),
84
				() => joinPathToBase(env.get('LOCALAPPDATA'), ['Temp']),
85
				() => joinPathToBase(Adapt.home(adapter_)(), ['AppData', 'Local', 'Temp']),
86
				() => joinPathToBase(env.get('ALLUSERSPROFILE'), ['Temp']),
87
				() => joinPathToBase(env.get('SystemRoot'), ['Temp']),
88
				() => joinPathToBase(env.get('windir'), ['Temp']),
89
				() => joinPathToBase(env.get('SystemDrive'), ['\\', 'Temp']),
90
			];
91
			const v = priorityListLazy.find((v) => v && !isEmpty(v()));
92
			return (v && normalizePath(v())) || fallback;
93
		};
94
95
		return isWinOS ? windows : posix;
96
	};
97
}
98
99
export function OSPathsAdaptionBuilder_(adapter_: Platform.Adapter): OSPaths {
100
	function OSPaths(): OSPaths {
101
		return obj as OSPaths;
102
	}
103
	const home = Adapt.home(adapter_);
104
	const temp = Adapt.temp(adapter_);
105
106
	// retouch method names
107
	Object.defineProperty(home, 'name', { value: 'home' });
108
	Object.defineProperty(temp, 'name', { value: 'temp' });
109
110
	const obj = Object.assign(OSPaths, {
111
		home,
112
		temp,
113
	}) as OSPaths;
114
	return obj as OSPaths;
115
}
116